﻿//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
// Exo² ffa01
// Copyright (C) 2007-2008 Samuel Lacroix and Raphaël Legouge
//
// Distributed under GNU General Public License
// See the License folder of Exo² for details
//
//
// http://www.codeplex.com/exo2 (eng)
//-----------------------------------------------------------------------------


#include "stdafx.h"
#pragma hdrstop
#include "gui.h"


#include "ffa 01.h"


namespace GUI {


tstring CButton::StateSpriteFileName =_T("");
tstring CCheckBox::StateSpriteFileName =_T("");
tstring CHorizontalSlider::StateSpriteFileName =_T("");
tstring CVerticalSlider::StateSpriteFileName =_T("");
tstring CTextButton::StateSpriteFileName =_T("");


void RegisterComponents()
{
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("button"), CreateButtonCallback);
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("checkbox"), CreateCheckBoxCallback);
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("label"), CreateLabelCallback);
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("hslider"), CreateHorizontalSliderCallback);
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("vslider"), CreateVerticalSliderCallback);
        Exo2::CMenuManager::Instance().ComponentFactory.Register(_T("textbutton"), CreateTextButtonCallback);
}


Exo2::CMenuComponent* CreateButtonCallback(void* /*pUserData*/)
{
        return new CButton;
}


Exo2::CMenuComponent* CreateCheckBoxCallback(void* /*pUserData*/)
{
        return new CCheckBox;
}


Exo2::CMenuComponent* CreateLabelCallback(void* /*pUserData*/)
{
        return new CLabel;
}


Exo2::CMenuComponent* CreateHorizontalSliderCallback(void* /*pUserData*/)
{
        return new CHorizontalSlider;
}


Exo2::CMenuComponent* CreateVerticalSliderCallback(void* /*pUserData*/)
{
        return new CVerticalSlider;
}


Exo2::CMenuComponent* CreateTextButtonCallback(void* /*pUserData*/)
{
        return new CTextButton;
}


void CButton::LoadStateSprites()
{
    // Fichier qui contient les infos de chargement
        boost::shared_ptr<Exo2::CXMLFile> pStateSpriteFile = Exo2::CResourceManager::Instance().GetResource<Exo2::CXMLFile>(CButton::StateSpriteFileName);
        boost::shared_ptr<Exo2::CXMLSection> pXMLSection = pStateSpriteFile->pRoot->GetChildren(_T("cbutton"))[0];      // Un peu bourrin de ne prendre que le premier
                   
        const Exo2::CXMLSection::TChildren& Children = pXMLSection->GetChildren(_T("texture"));
        for (size_t i = 0; i < Children.size(); ++i)        // Pour chaque texture enregistrée dans le fichier
        {
                const boost::shared_ptr<Exo2::CXMLSection>& pChild = Children[i];
        
                // On charge la texture du sprite
                boost::shared_ptr<Exo2::CTexture> pTexture;
                pTexture = Exo2::CResourceManager::Instance().GetResource<Exo2::CTexture>(pChild->GetAttribute(_T("filename")));        
                
                // On charge le rectangle
                boost::shared_ptr<Exo2::CXMLSection> pRectSection = pChild->GetChildren(_T("rect"))[0];
                long Left   = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("left")));
                long Top    = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("top")));
                long Right  = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("right")));
                long Bottom = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("bottom")));
                boost::shared_ptr<Exo2::CRect> pRect;
                pRect.reset(new Exo2::CRect(Left, Top, Right, Bottom));
                
                // On charge le StateSprite
                boost::shared_ptr<Exo2::CStateSprite<> > pStateSprite;
                pStateSprite.reset(new Exo2::CStateSprite<>(Exo2::SSRM_NONE));
                pStateSprite->SetTexture(pTexture);
                pStateSprite->SetSrcRect(pRect);
                
                // Pour chaque masque
                const Exo2::CXMLSection::TChildren& Masks = pChild->GetChildren(_T("mask"));
                for (size_t j = 0; j < Masks.size(); ++j)
                {
                        boost::shared_ptr<Exo2::CXMLSection> pMaskSection = Masks[j];
                
                        tstring Name = pMaskSection->GetAttribute(_T("name"));
                        D3DXCOLOR Color = Exo2::Utils::StringToValue<D3DXCOLOR>(pMaskSection->GetAttribute(_T("color")));
                        float Fade = Exo2::Utils::StringToValue<float>(pMaskSection->GetAttribute(_T("fade")));
                        pStateSprite->ColorMaskEffects[Name] = Exo2::ColorEffect(Color, Fade);
                }
                
                // Enregistrement
                this->StateSprites.push_back(pStateSprite);
        }
}

void CCheckBox::LoadStateSprites()
{
    // Fichier qui contient les infos de chargement
        boost::shared_ptr<Exo2::CXMLFile> pStateSpriteFile = Exo2::CResourceManager::Instance().GetResource<Exo2::CXMLFile>(CCheckBox::StateSpriteFileName);
        boost::shared_ptr<Exo2::CXMLSection> pXMLSection = pStateSpriteFile->pRoot->GetChildren(_T("ccheckbox"))[0];      // Un peu bourrin de ne prendre que le premier
                   
        const Exo2::CXMLSection::TChildren& Children = pXMLSection->GetChildren(_T("texture"));
        for (size_t i = 0; i < Children.size(); ++i)        // Pour chaque texture enregistrée dans le fichier
        {
                const boost::shared_ptr<Exo2::CXMLSection>& pChild = Children[i];
        
                // On charge la texture du sprite
                boost::shared_ptr<Exo2::CTexture> pTexture;
                pTexture = Exo2::CResourceManager::Instance().GetResource<Exo2::CTexture>(pChild->GetAttribute(_T("filename")));        
                
                // On charge le rectangle
                boost::shared_ptr<Exo2::CXMLSection> pRectSection = pChild->GetChildren(_T("rect"))[0];
                long Left   = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("left")));
                long Top    = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("top")));
                long Right  = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("right")));
                long Bottom = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("bottom")));
                boost::shared_ptr<Exo2::CRect> pRect;
                pRect.reset(new Exo2::CRect(Left, Top, Right, Bottom));
                
                // On charge le StateSprite
                boost::shared_ptr<Exo2::CStateSprite<> > pStateSprite;
                pStateSprite.reset(new Exo2::CStateSprite<>(Exo2::SSRM_NONE));
                pStateSprite->SetTexture(pTexture);
                pStateSprite->SetSrcRect(pRect);
                
                // Pour chaque masque
                const Exo2::CXMLSection::TChildren& Masks = pChild->GetChildren(_T("mask"));
                for (size_t j = 0; j < Masks.size(); ++j)
                {
                        boost::shared_ptr<Exo2::CXMLSection> pMaskSection = Masks[j];
                
                        tstring Name = pMaskSection->GetAttribute(_T("name"));
                        D3DXCOLOR Color = Exo2::Utils::StringToValue<D3DXCOLOR>(pMaskSection->GetAttribute(_T("color")));
                        float Fade = Exo2::Utils::StringToValue<float>(pMaskSection->GetAttribute(_T("fade")));
                        pStateSprite->ColorMaskEffects[Name] = Exo2::ColorEffect(Color, Fade);
                }
                
                // Enregistrement
                this->StateSprites.push_back(pStateSprite);
        }
}

CHorizontalSlider::CHorizontalSlider()
{
        this->MinMargin = 4;    // Ne pas mettre ça en dur
        this->MaxMargin = 4;
}

void CHorizontalSlider::LoadStateSprites()
{    
    // Fichier qui contient les infos de chargement
        boost::shared_ptr<Exo2::CXMLFile> pStateSpriteFile = Exo2::CResourceManager::Instance().GetResource<Exo2::CXMLFile>(CHorizontalSlider::StateSpriteFileName);
        boost::shared_ptr<Exo2::CXMLSection> pXMLSection = pStateSpriteFile->pRoot->GetChildren(_T("chslider"))[0];      // Un peu bourrin de ne prendre que le premier
                   
        const Exo2::CXMLSection::TChildren& Children = pXMLSection->GetChildren(_T("texture"));
        for (size_t i = 0; i < Children.size(); ++i)        // Pour chaque texture enregistrée dans le fichier
        {
                const boost::shared_ptr<Exo2::CXMLSection>& pChild = Children[i];
        
                // On charge la texture du sprite
                boost::shared_ptr<Exo2::CTexture> pTexture;
                pTexture = Exo2::CResourceManager::Instance().GetResource<Exo2::CTexture>(pChild->GetAttribute(_T("filename")));        
                
                // On charge le rectangle
                boost::shared_ptr<Exo2::CXMLSection> pRectSection = pChild->GetChildren(_T("rect"))[0];
                long Left   = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("left")));
                long Top    = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("top")));
                long Right  = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("right")));
                long Bottom = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("bottom")));
                boost::shared_ptr<Exo2::CRect> pRect;
                pRect.reset(new Exo2::CRect(Left, Top, Right, Bottom));
                
                // On regarde quel type de state sprite c'est
                boost::shared_ptr<Exo2::CMenuHorizontalSlider::CSliderSprite> pSliderSprite;
                Exo2::CMenuHorizontalSlider::SLIDER_SPRITE_USAGE Usage = Exo2::CMenuHorizontalSlider::SSU_NONE;
                tstring SpriteUsage = pChild->GetAttribute(_T("usage"));
                if (SpriteUsage == _T("thumb"))
                    Usage = Exo2::CMenuHorizontalSlider::SSU_THUMB;
                else if (SpriteUsage == _T("left"))
                    Usage = Exo2::CMenuHorizontalSlider::SSU_LEFT;
                else if (SpriteUsage == _T("right"))
                    Usage = Exo2::CMenuHorizontalSlider::SSU_RIGHT;
                
                pSliderSprite.reset(new Exo2::CMenuHorizontalSlider::CSliderSprite(Usage, Exo2::SSRM_NONE));

                pSliderSprite->SetTexture(pTexture);
                pSliderSprite->SetSrcRect(pRect);
                
                // Pour chaque masque
                const Exo2::CXMLSection::TChildren& Masks = pChild->GetChildren(_T("mask"));
                for (size_t j = 0; j < Masks.size(); ++j)
                {
                        boost::shared_ptr<Exo2::CXMLSection> pMaskSection = Masks[j];
                
                        tstring Name = pMaskSection->GetAttribute(_T("name"));
                        D3DXCOLOR Color = Exo2::Utils::StringToValue<D3DXCOLOR>(pMaskSection->GetAttribute(_T("color")));
                        float Fade = Exo2::Utils::StringToValue<float>(pMaskSection->GetAttribute(_T("fade")));
                        pSliderSprite->ColorMaskEffects[Name] = Exo2::ColorEffect(Color, Fade);
                }
                
                // Enregistrement
                this->StateSprites.push_back(pSliderSprite);        
        }
}

CVerticalSlider::CVerticalSlider()
{
        this->MinMargin = 4;    // Ne pas mettre ça en dur
        this->MaxMargin = 4;
}       


void CVerticalSlider::LoadStateSprites()
{
        // Fichier qui contient les infos de chargement
        boost::shared_ptr<Exo2::CXMLFile> pStateSpriteFile = Exo2::CResourceManager::Instance().GetResource<Exo2::CXMLFile>(CVerticalSlider::StateSpriteFileName);
        boost::shared_ptr<Exo2::CXMLSection> pXMLSection = pStateSpriteFile->pRoot->GetChildren(_T("cvslider"))[0];      // Un peu bourrin de ne prendre que le premier

        const Exo2::CXMLSection::TChildren& Children = pXMLSection->GetChildren(_T("texture"));
        for (size_t i = 0; i < Children.size(); ++i)        // Pour chaque texture enregistrée dans le fichier
        {
                const boost::shared_ptr<Exo2::CXMLSection>& pChild = Children[i];

                // On charge la texture du sprite
                boost::shared_ptr<Exo2::CTexture> pTexture;
                pTexture = Exo2::CResourceManager::Instance().GetResource<Exo2::CTexture>(pChild->GetAttribute(_T("filename")));        

                // On charge le rectangle
                boost::shared_ptr<Exo2::CXMLSection> pRectSection = pChild->GetChildren(_T("rect"))[0];
                long Left   = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("left")));
                long Top    = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("top")));
                long Right  = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("right")));
                long Bottom = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("bottom")));
                boost::shared_ptr<Exo2::CRect> pRect;
                pRect.reset(new Exo2::CRect(Left, Top, Right, Bottom));

                // On regarde quel type de state sprite c'est
                boost::shared_ptr<Exo2::CMenuVerticalSlider::CSliderSprite> pSliderSprite;
                Exo2::CMenuVerticalSlider::SLIDER_SPRITE_USAGE Usage = Exo2::CMenuVerticalSlider::SSU_NONE;
                tstring SpriteUsage = pChild->GetAttribute(_T("usage"));
                if (SpriteUsage == _T("thumb"))
                        Usage = Exo2::CMenuVerticalSlider::SSU_THUMB;
                else if (SpriteUsage == _T("top"))
                        Usage = Exo2::CMenuVerticalSlider::SSU_TOP;
                else if (SpriteUsage == _T("bottom"))
                        Usage = Exo2::CMenuVerticalSlider::SSU_BOTTOM;

                pSliderSprite.reset(new Exo2::CMenuVerticalSlider::CSliderSprite(Usage, Exo2::SSRM_NONE));

                pSliderSprite->SetTexture(pTexture);
                pSliderSprite->SetSrcRect(pRect);

                // Pour chaque masque
                const Exo2::CXMLSection::TChildren& Masks = pChild->GetChildren(_T("mask"));
                for (size_t j = 0; j < Masks.size(); ++j)
                {
                        boost::shared_ptr<Exo2::CXMLSection> pMaskSection = Masks[j];

                        tstring Name = pMaskSection->GetAttribute(_T("name"));
                        D3DXCOLOR Color = Exo2::Utils::StringToValue<D3DXCOLOR>(pMaskSection->GetAttribute(_T("color")));
                        float Fade = Exo2::Utils::StringToValue<float>(pMaskSection->GetAttribute(_T("fade")));
                        pSliderSprite->ColorMaskEffects[Name] = Exo2::ColorEffect(Color, Fade);
                }

                // Enregistrement
                this->StateSprites.push_back(pSliderSprite);
        }
}

void CTextButton::LoadStateSprites()
{
    // Fichier qui contient les infos de chargement
        boost::shared_ptr<Exo2::CXMLFile> pStateSpriteFile = Exo2::CResourceManager::Instance().GetResource<Exo2::CXMLFile>(CTextButton::StateSpriteFileName);
        boost::shared_ptr<Exo2::CXMLSection> pXMLSection = pStateSpriteFile->pRoot->GetChildren(_T("ctextbutton"))[0];      // Un peu bourrin de ne prendre que le premier
                   
        const Exo2::CXMLSection::TChildren& Children = pXMLSection->GetChildren(_T("texture"));
        for (size_t i = 0; i < Children.size(); ++i)        // Pour chaque texture enregistrée dans le fichier
        {
                const boost::shared_ptr<Exo2::CXMLSection>& pChild = Children[i];
        
                // On charge la texture du sprite
                boost::shared_ptr<Exo2::CTexture> pTexture;
                pTexture = Exo2::CResourceManager::Instance().GetResource<Exo2::CTexture>(pChild->GetAttribute(_T("filename")));        
                
                // On charge le rectangle
                boost::shared_ptr<Exo2::CXMLSection> pRectSection = pChild->GetChildren(_T("rect"))[0];
                long Left   = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("left")));
                long Top    = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("top")));
                long Right  = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("right")));
                long Bottom = Exo2::Utils::StringToValue<long>(pRectSection->GetAttribute(_T("bottom")));
                boost::shared_ptr<Exo2::CRect> pRect;
                pRect.reset(new Exo2::CRect(Left, Top, Right, Bottom));
                
                // On charge le StateSprite
                boost::shared_ptr<Exo2::CStateSprite<> > pStateSprite;
                pStateSprite.reset(new Exo2::CStateSprite<>(Exo2::SSRM_NONE));
                pStateSprite->SetTexture(pTexture);
                pStateSprite->SetSrcRect(pRect);
                
                // Pour chaque masque
                const Exo2::CXMLSection::TChildren& Masks = pChild->GetChildren(_T("mask"));
                for (size_t j = 0; j < Masks.size(); ++j)
                {
                        boost::shared_ptr<Exo2::CXMLSection> pMaskSection = Masks[j];
                
                        tstring Name = pMaskSection->GetAttribute(_T("name"));
                        D3DXCOLOR Color = Exo2::Utils::StringToValue<D3DXCOLOR>(pMaskSection->GetAttribute(_T("color")));
                        float Fade = Exo2::Utils::StringToValue<float>(pMaskSection->GetAttribute(_T("fade")));
                        pStateSprite->ColorMaskEffects[Name] = Exo2::ColorEffect(Color, Fade);
                }
                
                // Enregistrement
                this->StateSprites.push_back(pStateSprite);
        }
}

void COnResolutionChange::OnNewResolution()
{
        // Pour les changements d'options en temps réel (entre autre la résolution)
        OptionsModified();
        this->pMenuDataManager->LoadDataFromApplication(_T("options"));
        this->pMenuDataManager->UpdateComponentFromData(_T("options"));        
}

void OnClickTextButtonProfil(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        This->pMenuDataManager->LoadDataFromApplication(_T("profil"));
        This->pMenuDataManager->UpdateComponentFromData(_T("profil"));
        Exo2::CMenuManager::Instance().EnterMenu(_T("profil"));
}

void OnClickTextButtonHost(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        This->pMenuDataManager->LoadDataFromApplication(_T("host"));
        This->pMenuDataManager->UpdateComponentFromData(_T("host"));
        Exo2::CMenuManager::Instance().EnterMenu(_T("host"));
}

void OnClickTextButtonJoin(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        This->pMenuDataManager->LoadDataFromApplication(_T("join"));
        This->pMenuDataManager->UpdateComponentFromData(_T("join"));
        Exo2::CMenuManager::Instance().EnterMenu(_T("join"));
}

void OnClickTextButtonOptions(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        This->pMenuDataManager->LoadDataFromApplication(_T("options"));
        This->pMenuDataManager->UpdateComponentFromData(_T("options"));
        Exo2::CMenuManager::Instance().EnterMenu(_T("options"));
}

void OnClickTextButtonCredits(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        This->pMenuDataManager->LoadDataFromApplication(_T("credits"));
        This->pMenuDataManager->UpdateComponentFromData(_T("credits"));
        Exo2::CMenuManager::Instance().EnterMenu(_T("credits"));
}

void OnClickTextButtonExit(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        MenuBeforeExit = Exo2::CMenuManager::Instance().GetCurrentMenuName();
        This->pMenuDataManager->LoadDataFromApplication(_T("exit"));
        This->pMenuDataManager->UpdateComponentFromData(_T("exit"));
        Exo2::CMenuManager::Instance().EnterMenu(_T("exit"));
}

void OnClickTextButtonOptionsApply(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        This->pMenuDataManager->UpdateApplicationFromData(_T("options"));
        This->pMenuDataManager->LoadDataFromApplication(_T("options"));
        This->pMenuDataManager->UpdateComponentFromData(_T("options"));
        
        boost::shared_ptr<Exo2::CMenuComponent> pComponent;
        pComponent = Exo2::CMenuManager::Instance().GetComponent(_T("textbuttonoptionsapply"), _T("options"));
        pComponent->Enabled->Set(false);
        
        pComponent = Exo2::CMenuManager::Instance().GetComponent(_T("textbuttonoptionscancel"), _T("options"));
        pComponent->Enabled->Set(false);
        // Appliquer ce qui est dans CMenuOption::pOptionsData
}

void OnClickTextButtonOptionsCancel(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        This->pMenuDataManager->LoadDataFromApplication(_T("options"));
        This->pMenuDataManager->UpdateComponentFromData(_T("options"));
        
        boost::shared_ptr<Exo2::CMenuComponent> pComponent;
        pComponent = Exo2::CMenuManager::Instance().GetComponent(_T("textbuttonoptionsapply"), _T("options"));
        pComponent->Enabled->Set(false);
        
        pComponent = Exo2::CMenuManager::Instance().GetComponent(_T("textbuttonoptionscancel"), _T("options"));
        pComponent->Enabled->Set(false);
}

void OnClickTextButtonOptionsDefaults(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        
        std::wostringstream oss;
        oss.str(_T(""));
        
    // Graphics
        // Résolution
        oss << _T("revert res;");
        
        // Synchro verticale
        oss << _T("revert vsync;");
        
        // Windowed
        oss << _T("revert windowed;");
        
        // Filtrage
        // TODO
        
    // Audio
        // Audio device
        // TODO
        
        // Master volume
        oss << _T("revert volume;");
        
        // Music volume
        // TODO
        
        // Effects volume
        // TODO
        
    // Physics
        // Time Step
        oss << _T("revert timestep;");
    
        // Particle Limitation
        oss << _T("revert particlelimitation;");
    
        This->Shell().Execute(oss.str(), Exo2::CShell::DevScope);
        
        
        This->pMenuDataManager->LoadDataFromApplication(_T("options"));
        This->pMenuDataManager->UpdateComponentFromData(_T("options"));
        
        OptionsModified();
}

void OnClickTextButtonOptionsGraphicsResolutionPrev(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        pData->ResolutionList.push_front(pData->ResolutionList.back());
        pData->ResolutionList.pop_back();
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsgraphicsresolutionvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(pData->ResolutionList.front());
        OptionsModified();
}

void OnClickTextButtonOptionsGraphicsResolutionNext(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        pData->ResolutionList.push_back(pData->ResolutionList.front());
        pData->ResolutionList.pop_front();
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsgraphicsresolutionvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(pData->ResolutionList.front());
        OptionsModified();
}

void OnClickCheckBoxOptionsGraphicsSyncVert(Exo2::CMenuComponent* pSender, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        CCheckBox* pCheckBox = static_cast<CCheckBox*>(pSender);
        EXO_ASSERT(pCheckBox != NULL);
        pData->VSync = pCheckBox->Checked->Get();
        OptionsModified();
}

void OnClickCheckBoxOptionsGraphicsWindowed(Exo2::CMenuComponent* pSender, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        CCheckBox* pCheckBox = static_cast<CCheckBox*>(pSender);
        EXO_ASSERT(pCheckBox != NULL);
        pData->Windowed = pCheckBox->Checked->Get();
        OptionsModified();
}

void OnClickTextButtonOptionsGraphicsFiltrationPrev(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        pData->FiltrationList.push_front(pData->FiltrationList.back());
        pData->FiltrationList.pop_back();
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsgraphicsfiltrationvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(pData->FiltrationList.front());
        OptionsModified();
        
}

void OnClickTextButtonOptionsGraphicsFiltrationNext(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        pData->FiltrationList.push_back(pData->FiltrationList.front());
        pData->FiltrationList.pop_front();
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsgraphicsfiltrationvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(pData->FiltrationList.front());
        OptionsModified();
}

void OnClickTextButtonOptionsAudioDevicePrev(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        pData->AudioDeviceList.push_front(pData->AudioDeviceList.back());
        pData->AudioDeviceList.pop_back();
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsaudiodevicevalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(pData->AudioDeviceList.front());
        OptionsModified();
}

void OnClickTextButtonOptionsAudioDeviceNext(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        pData->AudioDeviceList.push_back(pData->AudioDeviceList.front());
        pData->AudioDeviceList.pop_front();
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsaudiodevicevalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(pData->AudioDeviceList.front());
        OptionsModified();
}

void OnChangeSliderOptionsAudioMaster(Exo2::CMenuComponent* pSender, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        CHorizontalSlider* pSlider = static_cast<CHorizontalSlider*>(pSender);
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsaudiomastervalue"), _T("options")));
        EXO_ASSERT(pLabel);
        std::wostringstream oss;
        oss << pSlider->Pos->Get() << _T(" %");
        pLabel->Text->Set(oss.str());
        pData->MasterVolume = pSlider->Pos->Get();
        OptionsModified();
        
}

void OnChangeSliderOptionsAudioMusic(Exo2::CMenuComponent* pSender, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        CHorizontalSlider* pSlider = static_cast<CHorizontalSlider*>(pSender);
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsaudiomusicvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        std::wostringstream oss;
        oss << pSlider->Pos->Get() << _T(" %");
        pLabel->Text->Set(oss.str());
        pData->MusicVolume = pSlider->Pos->Get();
        OptionsModified();
}

void OnChangeSliderOptionsAudioEffects(Exo2::CMenuComponent* pSender, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        CHorizontalSlider* pSlider = static_cast<CHorizontalSlider*>(pSender);
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsaudioeffectsvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        std::wostringstream oss;
        oss << pSlider->Pos->Get() << _T(" %");
        pData->EffectsVolume = pSlider->Pos->Get();
        pLabel->Text->Set(oss.str());
        OptionsModified();
}

void OnChangeSliderOptionsPhysicsAccuracy(Exo2::CMenuComponent* pSender, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        CHorizontalSlider* pSlider = static_cast<CHorizontalSlider*>(pSender);
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsphysicsaccuracyvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pData->TimeStep = 1. / pSlider->Pos->Get();
        std::wostringstream oss;
        oss << pSlider->Pos->Get() << _T(" fps");
        pLabel->Text->Set(oss.str());
        OptionsModified();
}

void OnChangeSliderOptionsPhysicsParticleLimitation(Exo2::CMenuComponent* pSender, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataOptions> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataOptions>(This->pMenuDataManager->GetData(_T("options")));
        EXO_ASSERT(pData);
        CHorizontalSlider* pSlider = static_cast<CHorizontalSlider*>(pSender);
        boost::shared_ptr<CLabel> pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsphysicsparticlelimitationvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        std::wostringstream oss;
        oss << pSlider->Pos->Get() << _T(" %");
        pLabel->Text->Set(oss.str());
        pData->ParticleLimitation = double(pSlider->Pos->Get()) / 100;
        OptionsModified();
}

void OptionsModified()
{
        boost::shared_ptr<Exo2::CMenuComponent> pComponent;
        pComponent = Exo2::CMenuManager::Instance().GetComponent(_T("textbuttonoptionsapply"), _T("options"));
        pComponent->Enabled->Set(true);
        
        pComponent = Exo2::CMenuManager::Instance().GetComponent(_T("textbuttonoptionscancel"), _T("options"));
        pComponent->Enabled->Set(true);
}

void CMenuDataOptions::UpdateComponentFromData()
{
        boost::shared_ptr<CLabel> pLabel;
        boost::shared_ptr<CCheckBox> pCheckBox;
        boost::shared_ptr<CHorizontalSlider> pSlider;
        std::wostringstream oss;
        
        // Résolution
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsgraphicsresolutionvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(this->ResolutionList.front());
        
        // Synchro verticale
        pCheckBox = boost::dynamic_pointer_cast<CCheckBox>(Exo2::CMenuManager::Instance().GetComponent(_T("checkboxoptionsgraphicssyncvert"), _T("options")));
        EXO_ASSERT(pCheckBox);
        pCheckBox->Checked->Set(this->VSync);
        
        // Fénêtré
        pCheckBox = boost::dynamic_pointer_cast<CCheckBox>(Exo2::CMenuManager::Instance().GetComponent(_T("checkboxoptionsgraphicswindowed"), _T("options")));
        EXO_ASSERT(pCheckBox);
        pCheckBox->Checked->Set(this->Windowed);
        
        // Filtrage
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsgraphicsfiltrationvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(this->FiltrationList.front());
        
        // Audio Device
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsaudiodevicevalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(this->AudioDeviceList.front());
        
        // Master volume
        pSlider = boost::dynamic_pointer_cast<CHorizontalSlider>(Exo2::CMenuManager::Instance().GetComponent(_T("slideroptionsaudiomaster"), _T("options")));
        EXO_ASSERT(pSlider);
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsaudiomastervalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pSlider->Pos->Set(this->MasterVolume);
        oss.str(_T(""));
        oss << this->MasterVolume << _T(" %");
        pLabel->Text->Set(oss.str());
        
        // Music volume
        pSlider = boost::dynamic_pointer_cast<CHorizontalSlider>(Exo2::CMenuManager::Instance().GetComponent(_T("slideroptionsaudiomusic"), _T("options")));
        EXO_ASSERT(pSlider);
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsaudiomusicvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pSlider->Pos->Set(this->MusicVolume);
        oss.str(_T(""));
        oss << this->MusicVolume << _T(" %");
        pLabel->Text->Set(oss.str());
        
        // Effect volume
        pSlider = boost::dynamic_pointer_cast<CHorizontalSlider>(Exo2::CMenuManager::Instance().GetComponent(_T("slideroptionsaudioeffects"), _T("options")));
        EXO_ASSERT(pSlider);
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsaudioeffectsvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pSlider->Pos->Set(this->EffectsVolume);
        oss.str(_T(""));
        oss << this->EffectsVolume << _T(" %");
        pLabel->Text->Set(oss.str());
        
        // Time Step
        pSlider = boost::dynamic_pointer_cast<CHorizontalSlider>(Exo2::CMenuManager::Instance().GetComponent(_T("slideroptionsphysicsaccuracy"), _T("options")));
        EXO_ASSERT(pSlider);
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsphysicsaccuracyvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pSlider->Pos->Set(long(1. / this->TimeStep));
        oss.str(_T(""));
        oss << Exo2::Utils::Round<long, double>(1. / this->TimeStep) << _T(" fps");
        pLabel->Text->Set(oss.str());
        
        // Particle Limitation
        pSlider = boost::dynamic_pointer_cast<CHorizontalSlider>(Exo2::CMenuManager::Instance().GetComponent(_T("slideroptionsphysicsparticlelimitation"), _T("options")));
        EXO_ASSERT(pSlider);
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labeloptionsphysicsparticlelimitationvalue"), _T("options")));
        EXO_ASSERT(pLabel);
        pSlider->Pos->Set(Exo2::Utils::Round<long, double>(this->ParticleLimitation * 100));
        oss.str(_T(""));
        oss << pSlider->Pos->Get() << _T(" %");
        pLabel->Text->Set(oss.str());
}

void CMenuDataOptions::LoadDataFromApplication()
{
        // On réccupère les résolutions supportées
        Exo2::CDisplay::TResolutionList ResolutionList = Exo2::CApplication::Instance().Display().GetAvailableResolutions();
        
        // On ajouté la résolution courante et on stocke sa position dans un itérator
        Exo2::CDisplay::TResolutionList::const_iterator CurrentResolution = ResolutionList.insert(this->pApplication->Display().GetRes()).first;
        
        // On ajoute les résolutions à la liste des résolutions en retenant la position de la résolution courante
        this->ResolutionList.clear();
        size_t Index = 0;
        for (Exo2::CDisplay::TResolutionList::const_iterator pRes = ResolutionList.begin(); pRes != ResolutionList.end(); ++pRes)
        {
                if (*pRes < *CurrentResolution)
                    ++Index;
                std::wostringstream oss;
                oss << *pRes;
                this->ResolutionList.push_back(oss.str());
        }
        
        // On met la résolution courante en tête de la liste
        for (size_t i = 0; i < Index; ++i)
        {
                this->ResolutionList.push_back(this->ResolutionList.front());
                this->ResolutionList.pop_front();
        }
        
        // Réccupération de la synchro verticale
        this->VSync = this->pApplication->Display().GetVSync();
        
        // Réccupération du fenêtrage        
        this->Windowed = this->pApplication->Display().GetWindowed();
        
        // Réccupération des filtrages
        // TODO
        this->FiltrationList.push_back(_T("Bilinéaire"));
        this->FiltrationList.push_back(_T("Trilinéaire"));
        this->FiltrationList.push_back(_T("Anisotropique"));
        
        // Réccupération des Devices audio
        this->AudioDeviceList.clear();
        
        this->AudioDeviceList.push_back(_T("Test"));
        
        /*
        const std::map<tstring, std::string>& Devices = Exo2::CAudio::Instance().GetDeviceNames();
        for (std::map<tstring, std::string>::const_iterator pDevice = Devices.begin(); pDevice != Devices.end(); ++pDevice)
        {
                this->AudioDeviceList.push_back(pDevice->first);
        }*/
        /*
        // *** Plante car GetCurrentDeviceName retourne "" ***
        while (CMenuOptionData::pOptionData->AudioDeviceList.front() != Exo2::CAudio::Instance().GetCurrentDeviceName())
        {
                CMenuOptionData::pOptionData->AudioDeviceList.push_back(CMenuOptionData::pOptionData->AudioDeviceList.front());
                CMenuOptionData::pOptionData->AudioDeviceList.pop_front();
        }*/
        

        
        // Réccupération du volume général
        this->MasterVolume = 0;//size_t(100 * Exo2::CAudio::Instance().GetMasterVolume());
        
        // Réccupération du volume de la musique
        // TODO
        this->MusicVolume = 0;
        
        // Réccupération du volume des effets 
        // TODO
        this->EffectsVolume = 0;

        CFFA* pThis = static_cast<CFFA*>(this->pApplication);
        EXO_ASSERT(pThis != NULL);
        
        // Limitation des particules
        //this->ParticleLimitation = pThis->GetParticleLimitation()->Get();
        
        // Pas de calcul
        //this->TimeStep = pThis->GetTimeStep()->Get();
}

void CMenuDataOptions::UpdateApplicationFromData()
{
        std::wostringstream Cmd;
        Cmd.str(_T(""));
        
#define COMMAND(Name, Value) Cmd << (Name) << _T(" ") << (Value) << _T(";")
        
        // Résolution
        COMMAND(_T("Res"), this->ResolutionList.front());
                
        // Synchro vertical
        COMMAND(_T("VSync"), this->VSync);
        
        // Fênetrage
        COMMAND(_T("Windowed"), this->Windowed);
        
        // Filtrage
        
        
        // Device Audio
        
        
        // Master Volume
        COMMAND(_T("Volume"), this->MasterVolume);
        
        // Music Volume
        
        
        // Effects Volume
        
        
        // Time step
        COMMAND(_T("TimeStep"), this->TimeStep);
        
        // ParticleLimitation
        COMMAND(_T("ParticleLimitation"), this->ParticleLimitation);
        
#undef COMMAND
        this->pApplication->Shell().Execute(Cmd.str(), Exo2::CShell::DevScope);
}


void OnClickTextButtonHostCreate(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        MenuBeforeLoading = _T("host");
        Exo2::CMenuManager::Instance().EnterMenu(_T("loading"));
}

void OnClickTextButtonJoinJoinGame(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        MenuBeforeLoading = _T("join");
        Exo2::CMenuManager::Instance().EnterMenu(_T("loading"));
}

void OnClickTextButtonExitYes(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        ::PostQuitMessage(0);
}

void OnClickTextButtonExitNo(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        // *** Amélioration possible : retourner dans le menu ou on était quand on appuyé sur Exit (pas trop dur à faire en plus) ***
        Exo2::CMenuManager::Instance().EnterMenu(MenuBeforeExit);
        This->pMenuDataManager->LoadDataFromApplication(MenuBeforeExit);
        This->pMenuDataManager->UpdateComponentFromData(MenuBeforeExit);
}

void OnClickTextButtonProfilPlayerShipPrev(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataProfil> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataProfil>(This->pMenuDataManager->GetData(_T("profil")));
        EXO_ASSERT(pData);
        pData->ShipList.push_back(pData->ShipList.front());
        pData->ShipList.pop_front();
        
        This->pMenuDataManager->LoadDataFromComponent(_T("profil"));
        This->pMenuDataManager->UpdateComponentFromData(_T("profil"));

}

void OnClickTextButtonProfilPlayerShipNext(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<CMenuDataProfil> pData;
        pData = boost::dynamic_pointer_cast<CMenuDataProfil>(This->pMenuDataManager->GetData(_T("profil")));
        EXO_ASSERT(pData);
        pData->ShipList.push_front(pData->ShipList.back());
        pData->ShipList.pop_back();
        
        This->pMenuDataManager->LoadDataFromComponent(_T("profil"));
        This->pMenuDataManager->UpdateComponentFromData(_T("profil"));
}

void OnChangeSliderProfilActionScroll(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateComponentFromData();
}

void OnEnterLabelProfilAction(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        boost::shared_ptr<CLabel> pLabel;
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelprofilactionstatustitle"), _T("profil")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set((Exo2::CMenuManager::Instance().GetMenuStrings())(54));
}

void OnLeaveLabelProfilAction(Exo2::CMenuComponent* /*pSender*/, void* /*pUserData*/)
{
        boost::shared_ptr<CLabel> pLabel;
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelprofilactionstatustitle"), _T("profil")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(_T(""));
}

void OnClickLabelProfilAction0(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        
        ModifingAction();
        
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void OnClickLabelProfilAction1(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        
        ModifingAction();  
              
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void OnClickLabelProfilAction2(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        
        ModifingAction();
        
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void OnClickLabelProfilAction3(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        
        ModifingAction();
        
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void OnClickLabelProfilAction4(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        
        ModifingAction();
        
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void OnClickLabelProfilAction5(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);

        ModifingAction();
        
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void OnClickLabelProfilAction6(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        
        ModifingAction();
        
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void OnClickLabelProfilAction7(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);

        ModifingAction();
        
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void OnClickLabelProfilAction8(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);

        ModifingAction();
        
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void OnClickLabelProfilAction9(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);

        ModifingAction();
        
        boost::shared_ptr<IMenuData> pData;
        pData = This->pMenuDataManager->GetData(_T("profil"));
        pData->UpdateApplicationFromData();
        pData->UpdateComponentFromData();
}

void CMenuDataProfil::LoadDataFromApplication()
{
        // Vaisseaux
        this->ShipList.clear();
        this->ShipList.push_back(_T("Tie-fighter"));
        this->ShipList.push_back(_T("X-Wing"));
        this->ShipList.push_back(_T("Millenium falcon"));
        
        // Touches
        std::map<std::wstring, std::list<std::wstring> > ActionMap;
        //ActionMap = Exo2::CApplication::Instance().Input().GetBoundInputEvents();
        
        this->ActionList.clear();
        for (std::map<std::wstring, std::list<std::wstring> >::const_iterator pPair = ActionMap.begin(); pPair != ActionMap.end(); ++pPair)
        {
                boost::shared_ptr<std::list<std::wstring> > pList;
                pList.reset(new std::list<std::wstring>);
                pList->insert(pList->begin(), pPair->second.begin(), pPair->second.end());
                this->ActionList.push_back(std::make_pair(pPair->first, pList));
        }
}

void CMenuDataProfil::LoadDataFromComponent()
{
        
}

void CMenuDataProfil::UpdateComponentFromData()
{
        boost::shared_ptr<CLabel> pLabel;
        boost::shared_ptr<CVerticalSlider> pSlider;
        const size_t NumberOfActionDisplayed = 10;
        
        // Vaisseau
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelprofilplayership"), _T("profil")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(this->ShipList.front());
        
        // Actions
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelprofilactionstatustitle"), _T("profil")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set(_T(""));
        
        pSlider = boost::dynamic_pointer_cast<CVerticalSlider>(Exo2::CMenuManager::Instance().GetComponent(_T("sliderprofilactionscroll"), _T("profil")));
        EXO_ASSERT(pSlider);
        bool Enabled = this->ActionList.size() > NumberOfActionDisplayed;
        pSlider->Enabled->Set(Enabled);
        std::size_t NumberOfActionToDisplay = NumberOfActionDisplayed;
        if (Enabled)
            pSlider->Max->Set(0, this->ActionList.size() != NumberOfActionDisplayed);
        else
            NumberOfActionToDisplay = this->ActionList.size();
        
        
        for (std::size_t i = 0; i < NumberOfActionToDisplay; ++i)
        {
                const std::size_t ActionIndex = i + pSlider->Pos->Get();
                                                
                std::wostringstream oss;
                
                // Nom de l'action
                oss << _T("labelprofilactionactionname") << i;
                pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(oss.str().c_str(), _T("profil")));
                EXO_ASSERT(pLabel);
                pLabel->Text->Set(this->ActionList[ActionIndex].first);
                
                oss.str(_T(""));
                // Clef(s) associées
                oss << _T("labelprofilactionaction") << i;
                pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(oss.str().c_str(), _T("profil")));
                EXO_ASSERT(pLabel);
                oss.str(_T(""));
                bool IsFirst = true;
                const std::list<std::wstring>& List = *this->ActionList[ActionIndex].second;
                for (std::list<std::wstring>::const_iterator pShipName = List.begin(); pShipName != List.end(); ++pShipName)
                {
                        if (!IsFirst)
                            oss << _T("; ");
                        IsFirst = false;
                        oss << *pShipName;
                }
                pLabel->Text->Set(oss.str());
        }
        
}

void CMenuDataProfil::UpdateApplicationFromData()
{

}

void CMenuDataManager::LoadDataFromComponent(const std::wstring& MenuName)
{
        EXO_ASSERT(this->MenuData.count(MenuName) == 1);
        this->MenuData[MenuName]->LoadDataFromComponent();
}

void CMenuDataManager::LoadDataFromApplication(const std::wstring& MenuName)
{                                                  
        EXO_ASSERT(this->MenuData.count(MenuName) == 1);
        this->MenuData[MenuName]->LoadDataFromApplication();
}

void CMenuDataManager::UpdateComponentFromData(const std::wstring& MenuName)
{
        EXO_ASSERT(this->MenuData.count(MenuName) == 1);                                        
        this->MenuData[MenuName]->UpdateComponentFromData();
}

void CMenuDataManager::UpdateApplicationFromData(const std::wstring& MenuName)
{
        EXO_ASSERT(this->MenuData.count(MenuName) == 1);
        this->MenuData[MenuName]->UpdateApplicationFromData();
}

const boost::shared_ptr<IMenuData>& CMenuDataManager::GetData(const std::wstring& MenuName)
{
        EXO_ASSERT(this->MenuData.count(MenuName) == 1);
        return this->MenuData[MenuName];
}

void CMenuDataManager::SetData(const boost::shared_ptr<IMenuData>& pData, const std::wstring& MenuName)
{
        EXO_ASSERT(this->MenuData.count(MenuName) == 0);
        this->MenuData[MenuName] = pData;
}

void ModifingAction()
{
        boost::shared_ptr<CLabel> pLabel;
        pLabel = boost::dynamic_pointer_cast<CLabel>(Exo2::CMenuManager::Instance().GetComponent(_T("labelprofilactionstatustitle"), _T("profil")));
        EXO_ASSERT(pLabel);
        pLabel->Text->Set((Exo2::CMenuManager::Instance().GetMenuStrings())(47));
}

void OnClickTextButtonLoadingCancel(Exo2::CMenuComponent* /*pSender*/, void* pUserData)
{
        CFFA* This = static_cast<CFFA*>(pUserData);
        This->pMenuDataManager->LoadDataFromApplication(MenuBeforeLoading);
        This->pMenuDataManager->UpdateComponentFromData(MenuBeforeLoading);
        Exo2::CMenuManager::Instance().EnterMenu(MenuBeforeLoading);
}
}